require "import"
import "android.widget.GridView"
import "android.content.Context"
import "android.content.Intent"
import "java.util.Locale"
import "android.speech.SpeechRecognizer"
import "android.speech.RecognitionListener"
import "android.speech.RecognizerIntent"
import "java.util.Locale"
import "android.content.Intent"
import "android.preference.PreferenceManager"

function kill()
    speechRecognizer.destroy()
    speechRecognizer = nil
    return true
end

function l()
local languageCodes = {
    ["Afrikaans"] = "af",
    ["Albanian"] = "sq",
    ["Amharic"] = "am",
    ["Arabic"] = "ar",
    ["Armenian"] = "hy",
    ["Azerbaijani"] = "az",
    ["Basque"] = "eu",
    ["Belarusian"] = "be",
    ["Bengali"] = "bn",
    ["Bosnian"] = "bs",
    ["Bulgarian"] = "bg",
    ["Burmese"] = "my",
    ["Catalan"] = "ca",
    ["Cebuano"] = "ceb",
    ["Chinese (Simplified)"] = "zh-CN",
    ["Chinese (Traditional)"] = "zh-TW",
    ["Corsican"] = "co",
    ["Croatian"] = "hr",
    ["Czech"] = "cs",
    ["Danish"] = "da",
    ["Dutch"] = "nl",
    ["English"] = "en",
    ["Esperanto"] = "eo",
    ["Estonian"] = "et",
    ["Filipino"] = "fil",
    ["Finnish"] = "fi",
    ["French"] = "fr",
    ["Frisian"] = "fy",
    ["Galician"] = "gl",
    ["Georgian"] = "ka",
    ["German"] = "de",
    ["Greek"] = "el",
    ["Gujarati"] = "gu",
    ["Haitian Creole"] = "ht",
    ["Hausa"] = "ha",
    ["Hawaiian"] = "haw",
    ["Hebrew"] = "he",
    ["Hindi"] = "hi",
    ["Hmong"] = "hmn",
    ["Hungarian"] = "hu",
    ["Icelandic"] = "is",
    ["Igbo"] = "ig",
    ["Indonesian"] = "id",
    ["Irish"] = "ga",
    ["Italian"] = "it",
    ["Japanese"] = "ja",
    ["Javanese"] = "jv",
    ["Kannada"] = "kn",
    ["Kazakh"] = "kk",
    ["Khmer"] = "km",
    ["Kinyarwanda"] = "rw",
    ["Korean"] = "ko",
    ["Kurdish"] = "ku",
    ["Kyrgyz"] = "ky",
    ["Lao"] = "lo",
    ["Latin"] = "la",
    ["Latvian"] = "lv",
    ["Lithuanian"] = "lt",
    ["Luxembourgish"] = "lb",
    ["Macedonian"] = "mk",
    ["Malagasy"] = "mg",
    ["Malay"] = "ms",
    ["Malayalam"] = "ml",
    ["Maltese"] = "mt",
    ["Maori"] = "mi",
    ["Marathi"] = "mr",
    ["Mongolian"] = "mn",
    ["Nepali"] = "ne",
    ["Norwegian"] = "no",
    ["Nyanja"] = "ny",
    ["Odia (Oriya)"] = "or",
    ["Pashto"] = "ps",
    ["Persian"] = "fa",
    ["Polish"] = "pl",
    ["Portuguese"] = "pt",
    ["Punjabi"] = "pa",
    ["Romanian"] = "ro",
    ["Russian"] = "ru",
    ["Samoan"] = "sm",
    ["Scots Gaelic"] = "gd",
    ["Serbian"] = "sr",
    ["Sesotho"] = "st",
    ["Shona"] = "sn",
    ["Sindhi"] = "sd",
    ["Sinhala"] = "si",
    ["Slovak"] = "sk",
    ["Slovenian"] = "sl",
    ["Somali"] = "so",
    ["Spanish"] = "es",
    ["Sundanese"] = "su",
    ["Swahili"] = "sw",
    ["Swedish"] = "sv",
    ["Tajik"] = "tg",
    ["Tamil"] = "ta",
    ["Tatar"] = "tt",
    ["Telugu"] = "te",
    ["Thai"] = "th",
    ["Turkish"] = "tr",
    ["Turkmen"] = "tk",
    ["Ukrainian"] = "uk",
    ["Urdu"] = "ur",
    ["Uyghur"] = "ug",
    ["Uzbek"] = "uz",
    ["Vietnamese"] = "vi",
    ["Welsh"] = "cy",
    ["Xhosa"] = "xh",
    ["Yiddish"] = "yi",
    ["Yoruba"] = "yo",
    ["Zulu"] = "zu"
}

    local selectedLanguage = nil
    local items = {}

    -- Collect languages and sort them alphabetically
    local sortedLanguages = {}
    for lang, _ in pairs(languageCodes) do
        sortedLanguages[#sortedLanguages + 1] = lang
    end
    table.sort(sortedLanguages)

    -- Add sorted languages to the items array
    for _, lang in ipairs(sortedLanguages) do
        items[#items + 1] = lang
    end

-- Custom order for specific languages
local languagesOrder = {
    "Kannada", "Tamil", "English", "Telugu", "Malayalam", "Spanish",
    "Afrikaans", "Albanian", "Amharic", "Arabic", "Armenian", "Azerbaijani",
    "Basque", "Belarusian", "Bengali", "Bosnian", "Bulgarian", "Burmese",
    "Catalan", "Cebuano", "Chinese (Simplified)", "Chinese (Traditional)",
    "Corsican", "Croatian", "Czech", "Danish", "Dutch", "Esperanto",
    "Estonian", "Filipino", "Finnish", "French", "Frisian", "Galician",
    "Georgian", "German", "Greek", "Gujarati", "Haitian Creole", "Hausa",
    "Hawaiian", "Hebrew", "Hindi", "Hmong", "Hungarian", "Icelandic",
    "Igbo", "Indonesian", "Irish", "Italian", "Japanese", "Javanese",
    "Kazakh", "Khmer", "Kinyarwanda", "Korean", "Kurdish", "Kyrgyz", "Lao",
    "Latin", "Latvian", "Lithuanian", "Luxembourgish", "Macedonian",
    "Malagasy", "Malay", "Maltese", "Maori", "Marathi", "Mongolian",
    "Nepali", "Norwegian", "Nyanja", "Odia (Oriya)", "Pashto", "Persian",
    "Polish", "Portuguese", "Punjabi", "Romanian", "Russian", "Samoan",
    "Scots Gaelic", "Serbian", "Sesotho", "Shona", "Sindhi", "Sinhala",
    "Slovak", "Slovenian", "Somali", "Sundanese", "Swahili", "Swedish",
    "Tajik", "Tatar", "Thai", "Turkish", "Turkmen", "Ukrainian", "Urdu",
    "Uyghur", "Uzbek", "Vietnamese"
}

    local customOrderItems = {}
    for _, lang in ipairs(languagesOrder) do
        for i = 1, #items do
            if items[i] == lang then
                customOrderItems[#customOrderItems + 1] = items[i]
            end
        end
    end

    local layout = {
        GridView,
        id = "grid",
        numColumns = 1,
        layout_width = "fill",
        layout_height = "fill"
    }

    local dlg = LuaDialog(this)
    dlg.View = loadlayout(layout)
    grid.adapter = SingleLineAdapter(service, customOrderItems)

    -- Check if language has been selected before
    local sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this)
    local storedLanguage = sharedPrefs.getString("selectedLanguage", nil)
    if storedLanguage and languageCodes[storedLanguage] then
        selectedLanguage = storedLanguage
    else
        dlg.setTitle("Voice Dictation, v2.0")
    end

dlg.setButton("Exit", nil)
   .setButton("Connect on Telegram", function()
        local intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://t.me/jieshuofiles"))
        service.startActivity(intent)
   end)
        .show()

    grid.onItemClick = function(l, v)
        dlg.dismiss()
        task(500, function()
            local language = v.text
            languageCode = languageCodes[language]

            if languageCode then
                selectedLanguage = language -- Update the selected language
                -- Save the selected language to shared preferences
                local editor = sharedPrefs.edit()
                editor.putString("selectedLanguage", selectedLanguage)
                editor.apply()
                service.speak(language.. " language selected")
            end
        end)
    end
end

if speechRecognizer then
    kill()
    l()
else

    local substitutionTable = {
        ["chino"] = "Jieshuo"
    }

    function hasInternetConnection()
        local connectivityManager = this.getSystemService(Context.CONNECTIVITY_SERVICE)
        local networkInfo = connectivityManager.getActiveNetworkInfo()
        return networkInfo ~= nil and networkInfo.isConnected()
    end

    function kill()
        speechRecognizer.destroy()
        speechRecognizer = nil
        return true
    end

    function startListening()
        if not hasInternetConnection() then
            service.asyncSpeak("இணைய இணைப்பு இல்லை.இணைய இணைப்பை சரி பார்த்த பிறகு  மீண்டும் முயலவும்.")
            return false
        end

        local verbalizationDetected = false

        speechRecognizer = SpeechRecognizer.createSpeechRecognizer(this)

        speechListener = RecognitionListener{
            onResults = function(results)
                data = results.getParcelableArrayList(SpeechRecognizer.RESULTS_RECOGNITION)
                if data ~= nil and data.size() > 0 then
                    verbalizationDetected = true
                    local recognizedText = data.get(0)
                    local node = service.getEditText()
                    local editText = service.getText(node)

                    if editText and string.len(editText) > 0 then
                        recognizedText = " " .. recognizedText
                    end

                    -- Modify recognized text to end with a dot and a newline
--symbols
                    recognizedText = recognizedText .. ". "

                    service.insertText(node, recognizedText)
                    service.speak(recognizedText)
                    kill()
                end

                if not verbalizationDetected then
                    kill()
                    return false
                end
            end,
            onError = function()
                kill()
                return false
            end
        }

        recognizerIntent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)
        recognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM)
        recognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, languageCode)
        recognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, this.getPackageName())

        speechRecognizer.startListening(recognizerIntent)
        speechRecognizer.setRecognitionListener(speechListener)

        return true
    end

    startListening()
    return true
end